package com.ljb.baseadapter_listview;

import android.util.SparseArray;

/**
 * 条目模板的控制器
 * Created by lijianbin on 2016/12/13.
 */
public class ItemViewTemplateController<T> {

    //模板集合
    private SparseArray<ItemViewTemplate<T>> templates;

    public ItemViewTemplateController() {
        templates = new SparseArray<>();
    }

    /**
     * 获取模板的个数
     */
    public int getItemViewTemplatesCount() {
        return templates.size();
    }

    /**
     * 正常顺序添加模板
     */
    public ItemViewTemplateController<T> addTemplate(ItemViewTemplate<T> template) {
        int typeIndex = templates.size();
        if (template != null) {
            templates.put(typeIndex, template);
        }
        return this;
    }

    /**
     * 在指定的itemType的位置添加模板
     */
    public ItemViewTemplateController<T> addTemplate(int itemType, ItemViewTemplate<T> template) {
        if (templates.get(itemType) != null) {
            throw new IllegalArgumentException("An ItemViewTemplate is already registered for the itemType ="
                    + itemType +
                    ".Already registered ItemViewTemplate is"
                    + templates.get(itemType));
        }
        templates.put(itemType, template);
        return this;
    }

    /**
     * 从模板集合中移除指定模板
     */
    public ItemViewTemplateController<T> removeDelegate(ItemViewTemplate<T> template) {
        if (template == null) {
            throw new NullPointerException("ItemViewTemplate is null");
        }
        int indexToRemove = templates.indexOfValue(template);
        if (indexToRemove >= 0) {
            templates.removeAt(indexToRemove);
        }
        return this;
    }

    /**
     * 从模板集合中移除指定itemType的模板
     */
    public ItemViewTemplateController<T> removeTemplate(int itemType) {
        int indexToRemove = templates.indexOfKey(itemType);
        if (indexToRemove >= 0)
            templates.removeAt(indexToRemove);
        return this;
    }

    /**
     * 根据数据和位置获取条目所对应的模板类型
     */
    public int getItemViewType(T item, int position) {
        int templatesCount = templates.size();
        for (int i = 0; i < templatesCount; i++) {
            ItemViewTemplate<T> template = templates.valueAt(i);
            if (template.isForViewType(item, position)) {//判断模板是否符合该位置的item
                return templates.keyAt(i);
            }
        }
        throw new IllegalArgumentException("No ItemViewTemplate added that matches position="
                + position
                + " in data source");
    }

    /**
     * 根据模板获取该模板在集合中所对应的索引
     */
    public int getItemViewType(ItemViewTemplate<T> template) {
        return templates.indexOfValue(template);
    }

    /**
     * 根据位置和数据获取对应的模板
     */
    public ItemViewTemplate<T> getItemViewTemplate(T item, int position) {
        int templatesCount = templates.size();
        for (int i = templatesCount - 1; i >= 0; i--) {
            ItemViewTemplate<T> template = templates.valueAt(i);
            if (template.isForViewType(item, position)) {
                return template;
            }
        }
        throw new IllegalArgumentException(
                "No ItemViewTemplate added that matches position="
                        + position
                        + " in data source");
    }

    /**
     * 根据模板类型获取条目的布局id
     */
    public int getItemViewLayoutId(int viewType) {
        return templates.get(viewType).getItemViewLayoutId();
    }

    /**
     * 根据数据和位置获取条目的布局Id
     */
    public int getItemViewLayoutId(T item, int position) {
        return getItemViewTemplate(item, position).getItemViewLayoutId();
    }

    /**
     * 数据转化
     */
    public void convert(ViewHolder holder, T item, int position) {
        int templateCount = templates.size();
        for (int i = 0; i < templateCount; i++) {
            ItemViewTemplate<T> template = templates.valueAt(i);
            if (template.isForViewType(item, position)) {
                template.convert(holder, item, position);
                return;
            }
        }
        throw new IllegalArgumentException("No ItemViewTemplate added that matches position="
                + position
                + " in data source");
    }
}
